using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Web;
using System.Net.Mail;
using System.Configuration;
using System.Xml;

namespace ErrorSense.Client.ErrorApi
{
    [Serializable()]
    public sealed class ErrorApiAdapter
    {
        public static string ErrorLogDefaultName
        {
            get
            {
                return ErrorApiConfig.Current.ErrorLogName;
            }
        }

        public static void WriteLog(string logMessage)
        {
            WriteLog(logMessage, EventLogEntryType.Information);
        }

        public static void WriteLog(string logMessage, int entryType)
        {
            WriteLog(logMessage, (EventLogEntryType)entryType);
        }

        public static void WriteLog(string logMessage, EventLogEntryType entryType)
        {
            if (ErrorLogDefaultName.Length > 0)
                EventLog.WriteEntry(ErrorLogDefaultName, logMessage, entryType);
        }

        public static void WriteErrorLogWithData(string logMessage, EventLogEntryType entryType, byte[] data)
        {
            if (ErrorLogDefaultName.Length > 0)
                EventLog.WriteEntry(ErrorLogDefaultName, logMessage, entryType, 0, 0, data);
        }

        public static void WriteCounter(string counterCategory, string counterName, string instanceName, int changeValue)
        {
            System.Diagnostics.PerformanceCounter oCnt = new System.Diagnostics.PerformanceCounter(counterCategory, counterName, instanceName, false);
            switch (changeValue)
            {
                case 0:
                    oCnt.Increment();
                    break;
                case 1:
                    oCnt.Increment();
                    break;
                case -1:
                    oCnt.Decrement();
                    break;
                default:
                    oCnt.IncrementBy(changeValue);
                    break;
            }
            oCnt.Dispose();
        }

        public static void SendNotification(Exception exObject, bool applyExclusionsFilter)
        {
            if (exObject == null)
                return;

            if (applyExclusionsFilter)
            {
                try
                {
                    if (exObject.GetType() == typeof(System.Web.HttpUnhandledException) && exObject.InnerException != null)
                        exObject = exObject.InnerException;

                    MetaDataReader meta = new MetaDataReader();
                    if (!meta.EvaluateExclusions(ref exObject))
                        return;

                    ErrorApiAdapter.SendNotification(exObject);
                }
                catch (Exception oError)
                {
                    ErrorApiAdapter.SendNotification(oError);
                }
            }
            else
                SendNotification(exObject);
        }

        public static void SendNotification(Exception exObject)
        {
            if (!ErrorApiConfig.Current.IsActive) return; //exit if inactive
            if (ErrorApiConfig.Current.NotificationPoints.Count == 0) return; //exit if there is nothing to do
            if (ErrorSense.Client.Security.SecurityBridge.DetermineRecursionNumber() > 2) return; //this is recursive call from the ErrorSense itself; ignore it.

            string message = "";
            //collect extra info from attributes
            try
            {
                MetaDataReader meta = new MetaDataReader();
                if (!meta.EvaluateErrorMetaData(ref exObject))
                    return;
            }
            catch (Exception ex)
            {
                try
                {
                    message = ErrorMessageFormatter.FormatGenericEmailErrorMessage(exObject);
                    WriteLog(message, EventLogEntryType.Error);
                    message = ErrorMessageFormatter.FormatGenericEmailErrorMessage(ex);
                    WriteLog(message, EventLogEntryType.Error);
                }
                catch { }
            }

            //process notification
            try
            {
                XmlDocument oDoc = ErrorMessageFormatter.FormatGenericXmlErrorMessage(exObject);
                string emailBody = ErrorMessageFormatter.FormatGenericEmailErrorMessage(exObject);
                SendPreparedNotification(oDoc, emailBody);
            }
            catch (Exception ex)
            {
                try
                {
                    message = ErrorMessageFormatter.FormatGenericEmailErrorMessage(exObject);
                    WriteLog(message, EventLogEntryType.Error);
                    message = ErrorMessageFormatter.FormatGenericEmailErrorMessage(ex);
                    WriteLog(message, EventLogEntryType.Error);
                }
                catch { }
            }
        }

        public static void SendPreparedNotification(XmlDocument errorDoc, string emailBody)
        {
            if (ErrorSense.Client.Security.SecurityBridge.DetermineRecursionNumber() > 2) return; //this is recursive call from the ErrorSense itself; ignore it.

            ErrorApiProcessor api = new ErrorApiProcessor();
            api.ProcessEachNotificationPoint(errorDoc, emailBody);
        }
    }
}
